<template>
  <el-dialog
    v-model="changeDialogCustomer"
    title="坐标拾取" :close-on-click-modal="false"
    draggable :modal="false"
  >
    <el-form class="coordinate-pickup-form" :inline="true">
      <el-form-item>
        <el-autocomplete
          v-model="searchParam"
          :fetch-suggestions="searchComplete"
          value-key="name"
          placeholder="请输入搜索内容" popper-class="coordinate-pickup-autocomplete"
          @select="handleSelect"
        >
          <template #default="scope">
            <div>{{ scope.item.name }}</div>
            <div class="autocomplete-subtitle">
              <span v-if="scope.item.district">{{ scope.item.district }}</span>
              <span v-if="scope.item.address && scope.item.address.length > 0">{{ scope.item.address }}</span>
            </div>
          </template>
        </el-autocomplete>
      </el-form-item>
      <el-form-item>
        <el-input v-model="pickupForm.lnglat" placeholder="拾取坐标" />
      </el-form-item>
      <el-form-item>
        <el-input v-model="pickupForm.address" placeholder="地址" style="width: 300px;" />
      </el-form-item>
      <el-form-item>
        <el-button :disabled="!pickupForm.lnglat" type="primary" @click="submitHandler">确认</el-button>
      </el-form-item>
      <el-form-item>
        <el-checkbox v-model="isSatelliteLayer" label="卫星图" @change="setSatelliteLayer" />
      </el-form-item>
    </el-form>
    <div ref="coordinatePickupRef" class="coordinate-pickup" />
  </el-dialog>
</template>

<script lang="ts" setup>
import { onMounted, onUnmounted, computed, watch, nextTick, ref } from 'vue'
import { initAMap } from '@utils/amap'
import { ElMessage } from 'element-plus'

const props = withDefaults(defineProps<{
  modelValue: boolean,
  lnglat?: string,
  address?: string,
  regeocodeRequired: boolean
}>(), {
  regeocodeRequired: false
})
const emits = defineEmits(['change', 'update:modelValue', 'update:lnglat', 'update:address', 'open'])

onMounted(() => {
  props.modelValue && loadAMap()
})

const pickupForm = ref({
  lnglat: '',
  address: ''
})

// region TODO 组件显示
watch(() => props.modelValue, (nv) => {
  if (nv && !map) {
    nextTick(() => {
      loadAMap()
    })
  } else {
    placeSearch.clear()
    showMarker(props.lnglat, props.address)
    emits('open', map)
  }
})
const changeDialogCustomer = computed({
  get (): boolean {
    return props.modelValue
  },
  set (val) {
    emits('update:modelValue', val)
  }
})
// endregion

// region TODO 搜索表单
const searchParam = ref('')
// endregion

// region TODO Map
let AMap = null
let map = null
const coordinatePickupRef = ref<HTMLDivElement>()
// 初始化地图
function loadAMap () {
  initAMap({
    el: coordinatePickupRef.value,
    plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder']
  }).then(res => {
    AMap = res.AMap
    map = res.map
    // 卫星图层
    satelliteLayer = new AMap.TileLayer.Satellite()
    map.on('click', clickHandler)
    autoComplete = new AMap.Autocomplete({ city: '全国' })
    placeSearch = new AMap.PlaceSearch({ map, city: '全国', autoFitView: true })
    placeSearch.on('markerClick', placeMarkerClick)
    geocoder = new AMap.Geocoder()
    showMarker(props.lnglat, props.address)
    emits('open', { map, AMap })
  })
  // AMapLoader.load({
  //   ...aMapSettings.loadOptions,
  //   plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder']
  // }).then(function (_AMap) {
  //   AMap = _AMap
  //   // 卫星图层
  //   satelliteLayer = new AMap.TileLayer.Satellite()
  //   map.on('click', clickHandler)
  //   autoComplete = new AMap.Autocomplete({ city: '全国' })
  //   placeSearch = new AMap.PlaceSearch({ map, city: '全国', autoFitView: true })
  //   placeSearch.on('markerClick', placeMarkerClick)
  //   geocoder = new AMap.Geocoder()
  //   showMarker(props.lnglat, props.address)
  //   emits('open', { map, AMap })
  // })
}
// 地图的点击事件
const clickHandler = async (e: any) => {
  const { lng, lat } = e.lnglat
  const lnglat = `${lng},${lat}`
  const address = await getAddressBylnglat(lnglat)
  showMarker(lnglat, address)
}
onUnmounted(function () {
  map && map.off('click', clickHandler)
  map && map.destroy()
})
// endregion

// region TODO 自动补全-autoComplete
let autoComplete = null
// 搜索补全结果
const searchComplete = (queryString: string, cb: (arg: any) => void) => {
  const empty = []
  if (queryString.length === 0) {
    cb(empty)
  } else {
    autoComplete.search(queryString, function (status: string, result: any) {
      if (result.info === 'OK') {
        result.tips.unshift({ name: queryString })
        cb(result.tips)
      } else {
        cb(empty)
      }
    })
  }
}
// 输入框选择事件
function handleSelect (item: any) {
  if (!item.address || !item.location) {
    placeSearchHandler(item.name)
  } else {
    placeSearch.clear()
    const { lng, lat } = item.location
    const lnglat = [lng, lat].join(',')
    let address = item.district
    if (item.district.indexOf(item.name) === -1) {
      address += item.name
    }
    showMarker(lnglat, address)
  }
}
// endregion

// region TODO 位置搜索-placeSearch
let placeSearch = null
function placeSearchHandler (queryString) {
  placeSearch.search(queryString, function (status, result) {
    if (result.info === 'TIP_CITIES') {
      ElMessage.info('条件内结果过多请精确搜索')
    }
  })
}
function placeMarkerClick (e) {
  const { lng, lat } = e.data.location
  pickupForm.value.lnglat = `${lng},${lat}`
  const data = e.data
  let _address = data.pname
  if (data.pname !== data.cityname) {
    _address += data.cityname
  }
  _address += data.adname + data.name
  pickupForm.value.address = _address
}
// endregion

// region TODO 地址逆变器-Geocoder
let geocoder = null
let regeocode = null
// 存储逆变结果
function getAddressBylnglat (lnglat: string): Promise<string> {
  const position = lnglat.split(',')
  return new Promise(function (resolve) {
    geocoder.getAddress(position, function (status, result) {
      if (status === 'complete' && result.regeocode) {
        result.regeocode.lnglat = lnglat
        regeocode = result.regeocode
        resolve(result.regeocode.formattedAddress)
      } else {
        regeocode = null
        resolve('')
      }
    })
  })
}

// endregion

// region TODO 独立标记点
let marker = null
function showMarker (lnglat: string, address) {
  if (lnglat) {
    const position = lnglat.split(',')
    if (marker) {
      marker.setPosition(position)
      marker.setTitle(address || '-')
    } else {
      marker = new AMap.Marker({
        map, position, title: address
      })
    }
    map.setCenter(position)
    pickupForm.value = { lnglat, address }
  }
}
// endregion

// region TODO 卫星图
let satelliteLayer = null
const isSatelliteLayer = ref(false)
function setSatelliteLayer () {
  if (isSatelliteLayer.value) {
    map.add(satelliteLayer)
  } else {
    map.remove(satelliteLayer)
  }
}
// endregion

/**
 * 确认拾取的坐标
 */
const submitHandler = async () => {
  if (regeocode && regeocode.lnglat !== pickupForm.value.lnglat) regeocode = null
  if (props.regeocodeRequired && !regeocode && pickupForm.value.lnglat) {
    await getAddressBylnglat(pickupForm.value.lnglat)
  }
  emits('change', { value: pickupForm.value, regeocode })
  emits('update:lnglat', pickupForm.value.lnglat)
  emits('update:address', pickupForm.value.address)
  emits('update:modelValue', false)
}
</script>

<style lang="scss">
.coordinate-pickup-autocomplete {
  li {
    margin-bottom: 8px;
  }
  .autocomplete-subtitle{
    font-size: 12px;
    color: var(--el-text-color-secondary);
    line-height: 12px;
  }
}
</style>

<style lang="scss" scoped>
.coordinate-pickup-form::v-deep(.el-form-item) {
  margin-right: 16px;
}
.coordinate-pickup {
  height: 50vh;
  min-height: 400px;
  max-height: 920px;
}
</style>
